package air.live
{
	import flash.display.BitmapData;
	import flash.display.JPEGEncoderOptions;
	import flash.display.JPEGXREncoderOptions;
	import flash.display.PNGEncoderOptions;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.OutputProgressEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.utils.ByteArray;
	
	import consts.ConstData;
	import consts.LiveBitmapdate;
	
	public class LiveFile extends EventDispatcher
	{
		
		
		
		
		
		
		private static var instance:LiveFile;
		/**
		 *单例模式
		 *
		 **/
		public static function getInstance():LiveFile{
			if(!instance) instance=new LiveFile();
			return instance;
		}
		/***************************************************/
		
		
		/***************属性***********************************/
		
		private var file:File;
		private var _is_async:Boolean=true;
		private var _data:ByteArray=new ByteArray();
		private var stream:FileStream=new FileStream();
		private var _is_compress:Boolean=true;
		private var _nativePath:String;
		private var _url:String
		
		
		
		
		
		
		public function get jsonObject():Object{
			return JSON.parse(String(_data))
		}
		/** 
		 * 二进制数据 
		 * @return 
		 * 
		 */			
		public function get data():ByteArray
		{
			try{
				_data.uncompress()
			}
			catch(e:Error){
				
			}  
			return _data;
		} 
		/**
		 * 是否异步 
		 * @return 
		 * 
		 */		
		public function get is_async():Boolean { return _is_async; }		
		public function set is_async(value:Boolean):void
		{
			if (_is_async == value)
				return;
			_is_async = value;
		}
		
		/**
		 * 是否对数据压缩 
		 * @return 
		 * 
		 */		
		public function get is_compress():Boolean { return _is_compress; }		
		public function set is_compress(value:Boolean):void
		{
			if (_is_compress == value)
				return;   
			_is_compress = value;
			
		}
		
		
		
		
		/**
		 * 本机路径 
		 * @return 
		 * 
		 */		
		public function get nativePath():String { return _nativePath; }	
		
		public function get url():String{return _url}
		public function LiveFile()
		{
			stream.addEventListener(Event.COMPLETE, completeHand);
			stream.addEventListener(IOErrorEvent.IO_ERROR,errorHand);
			stream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS,outputHand)
			stream.addEventListener(Event.CLOSE,closeHand)
			
			//file.addEventListener(
		}
		
		/**
		 * 可从任何位置删除 
		 * @param path
		 * 
		 */		
		public function del_none(path:String):void{
			file=new File(path)
			del()
		}
		/**
		 * 从 应用程序已安装文件的文件夹 删除
		 * @param path
		 * 
		 */	
		public function del_applicationDirectory(path:String):void{
			file=File.applicationDirectory.resolvePath(path)	
			del()
		}
		/**
		 * 从应用程序专用文件夹删除 
		 * @param path
		 * 
		 */		
		public function del_applicationStorageDirectory(path:String):void{
			file=File.applicationStorageDirectory.resolvePath(path)	
			del()
		}
		/**
		 * 从桌面删除 
		 * @param path
		 * 
		 */		
		public function del_desktopDirectory(path:String):void{
			file=File.desktopDirectory.resolvePath(path)
			del()
		}
		/**
		 * 从我的文档删除 
		 * @param path
		 * 
		 */		
		public function del_documentsDirectory(path:String):void{
			file=File.documentsDirectory.resolvePath(path)
			del()
		}
		
		
		
		/** 
		 *  从 应用程序已安装文件的文件夹 读取
		 * @param path
		 * 
		 */		
		public function read_applicationDirectory(path:String):void{
			file=File.applicationDirectory.resolvePath(path)		
			read();
		}
		/** 
		 * 从应用程序的专用存储目录读取。
		 * @param path  
		 * 
		 */		
		public function read_applicationStorageDirectory(path:String):void{
			file=File.applicationStorageDirectory.resolvePath(path)
			
			read()			
		}
		/**
		 * 从桌面读取 
		 * @param path
		 * 
		 */		
		public function read_desktopDirectory(path:String):void{
			file=File.desktopDirectory.resolvePath(path)
			read()			
		}
		
		
		
		
		/**
		 * 从我的文档读取 
		 * @param path
		 * 
		 */		
		public function read_documentsDirectory(path:String):void{
			file=File.documentsDirectory.resolvePath(path)
			read()			
		}
		
		
		public function read_all(path:String):void{
			file=new File(path);
			read()
		}
		
		
		public function write_all(obj:Object,path:String):void{
			file=new File(path);
			write(obj);
		}
		/**
		 *  将obj写入到 应用程序已安装文件的文件夹
		 * @param obj 目前支持String,byteArray,XML 对象
		 * @param path
		 * 
		 */        
		public function write_applicationDirectory(obj:Object,path:String):void{
			file=File.applicationDirectory.resolvePath(path)
			write(obj)	
		}
		
		/**
		 *  将obj写入到 应用程序的专用存储目录。
		 * @param obj 目前支持String,byteArray,XML 对象
		 * @param path
		 * 
		 */        
		public function write_applicationStorageDirectory(obj:Object,path:String):void{
			file=File.applicationStorageDirectory.resolvePath(path)
			write(obj)	
		}
		
		/**
		 *  将obj写入到 桌面。
		 * @param obj 目前支持String,byteArray,XML 对象
		 * @param path
		 * 
		 */        
		public function write_desktopDirectory(obj:Object,path:String):void{
			file=File.desktopDirectory.resolvePath(path)
			write(obj)	
		}
		
		/**
		 *  将obj写入到 我的文档。
		 * @param obj 目前支持String,byteArray,XML 对象
		 * @param path
		 * 
		 */        
		public function write_documentsDirectory(obj:Object,path:String):void{
			file=File.documentsDirectory.resolvePath(path)
			
			write(obj)	
		}
		
		
		
		
		//写入
		private function write(obj:*):void{
			_nativePath=file.nativePath
			_url=file.url
			_data.length=0
			if(obj is String) _data.writeUTFBytes(String(obj));  //字符串
			if(obj is XML) _data.writeUTFBytes(String(xml_header(XML(obj)))); //XML
			if(obj is ByteArray) _data=ByteArray(obj);//bye
			if(obj is LiveBitmapdate) {
				var liveBitmap:LiveBitmapdate=obj as LiveBitmapdate
				var bitm:BitmapData=liveBitmap.bitmapdate
				switch(liveBitmap.form)
				{
					case LiveBitmapdate.JPEG:
					{
						bitm.encode(bitm.rect,new JPEGEncoderOptions(liveBitmap.quality),_data);
						break;
					}
						
					case LiveBitmapdate.PNG:
					{
						bitm.encode(bitm.rect,new PNGEncoderOptions(),_data);
						break;
					}
						
					case LiveBitmapdate.JPEG_XR:
					{
						bitm.encode(bitm.rect,new JPEGXREncoderOptions(),_data);
						break;
					}
						
					default:
					{
						break;
					}
				}
				
			}else{
				if(is_compress) _data.compress();
			}
			
			
			
			if(_is_async){
				stream.openAsync(new File(file.nativePath),FileMode.WRITE);
				stream.writeBytes(_data,0,_data.length)  					
			}else{
				stream.open(new File(file.nativePath),FileMode.WRITE);
				stream.writeBytes(_data,0,_data.length)
				stream.close();
			} 
		}
		
		
		//读取
		private function read():void{
			_data.length=0;//初始化
			if(!file.exists) return;//文件或目录不存在，直接返回
			if(_is_async){						
				stream.openAsync(file, FileMode.READ);	
				stream.readBytes(_data); 								 
			}else{
				try
				{
					stream.open(file,FileMode.READ);//读取文件
					stream.readBytes(_data); 
					stream.close();
				} 
				catch(error:Error) 
				{
					
				}
			}
		}
		
		
		
		private function del():void{
			if(!file.exists) return;//文件或目录不存在，直接返回
			if(is_async){
				
				file.deleteFileAsync()
			}else{
				file.deleteDirectory()
				//file.deleteFile()
			}
		}
		/*......................事件..............................*/		
		private function completeHand(e:Event):void {	
			
			stream.close();	
			dispatchEvent(new Event(Event.COMPLETE))
		}
		private function errorHand(e:IOErrorEvent):void{
			dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR))
		}
		private function outputHand(e:OutputProgressEvent):void{
			
			stream.close();
			dispatchEvent(new OutputProgressEvent(OutputProgressEvent.OUTPUT_PROGRESS))
			
			trace("outPut")
		}
		private function closeHand(e:Event):void{
			dispatchEvent(new Event(Event.CLOSE))
		}
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		private function xml_header(xml:XML):String{
			return String(ConstData.XML_HEAD+"\r\n"+xml.toString().replace(ConstData.PATTERN, "\r\n"))
		}
		
		
		public function dispose():void{
			stream.removeEventListener(Event.COMPLETE, completeHand);
			stream.removeEventListener(IOErrorEvent.IO_ERROR,errorHand);
			stream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS,outputHand)
			stream.removeEventListener(Event.CLOSE,closeHand)
			
		}
		
		
		/**
		 *清除内存占用
		 *
		 **/
		public static function dispose():void{
			//如有其他监听或者引用，请先处理再Null
			instance.dispose()
			if(instance) instance=null;
		}
		
		
	}
}